// Copyright (c) 2007, Brian Duff

// See LICENSE for full license details.

package org.dubh.jdant;

import java.net.URL;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A read only version of the HashStructure API, which is the memory model 
 * used for many of the XML-persisted data structures in the Oracle IDE 
 * framework, including project files.<p>
 *
 * This class intentionally has no dependencies on the IDE framework. It
 * depends only on standard J2SE APIs.<p>
 *
 * This API is a highly restricted version of the real hash structure
 * API used by the Oracle IDE internally, and is not guaranteed to always
 * return the same values as its more comprehensive cousin. It does not 
 * support placeholders, for example.<p>
 * 
 * Obtain an instance of this class using the {@link ROHashStructureIO} 
 * API.
 * 
 * @author brian.duff@dubh.org
 */
public final class ROHashStructure
{
  private final Map<String,Object> _data;
  
  ROHashStructure( Map<String,Object> data )
  {
    _data = data;
  }
  
  public boolean containsKey( String name )
  {
    return _data.containsKey( name );
  }
  
  public boolean getBoolean( String name )
  {
    return Boolean.valueOf( getString( name ) );
  }
  
  public boolean getBoolean( String name, boolean defaultValue )
  {
    String value = getString( name );
    return value == null ? defaultValue : Boolean.valueOf( value );
  }
  
  public double getDouble( String name )
  {
    return Double.valueOf( getString( name ) );
  }
  
  public double getDouble( String name, double defaultValue )
  {
    String value = getString( name );
    return value == null ? defaultValue : Double.valueOf( value );
  }
  
  public float getFloat( String name )
  {
    return Float.valueOf( getString( name ) );
  }
  
  public float getFloat( String name, float defaultValue )
  {
    String value = getString( name );
    return value == null ? defaultValue : Float.valueOf( value );
  }
  
  public ROHashStructure getHashStructure( String name )
  {
    Object map = getObject( name );
    if ( map == null ) return null;
    if ( map instanceof ROHashStructure ) return (ROHashStructure) map;
    return new ROHashStructure( (Map<String,Object>)map );
  }
  
  public int getInt( String name )
  {
    return Integer.valueOf( getString( name ) );
  }
  
  public int getInt( String name, int defaultValue )
  {
    String value = getString( name );
    return value == null ? defaultValue : Integer.valueOf( value );
  }
  
  public List<ROHashStructure> getListOfHash( String name )
  {
    List<ROHashStructure> data = (List<ROHashStructure>) getObject( name );
    if (data == null)
      return null;
    return Collections.unmodifiableList( data );
  }
  
  public List<URL> getListOfURL( String name )
  {
    List<URL> data = (List<URL>) getObject( name );
    if (data == null)
      return null;
    return Collections.unmodifiableList( data );
  }
  
  public List<Object> getListStructure( String name )
  {
    List<Object> data = (List<Object>) getObject( name );
    if ( data == null ) return null;
    return Collections.unmodifiableList( data );
  }
  
  public long getLong( String name )
  {
    return Long.valueOf( getString( name ) );
  }
  
  public long getLong( String name, long defaultValue )
  {
    String value = getString( name );
    return value == null ? defaultValue : Long.valueOf( value );
  }
  
  public Object getObject( String name )
  {
    int firstSep = name.indexOf( '/' );
    if ( firstSep == -1 ) return _data.get( name );
    
    String firstHash = name.substring( 0, firstSep );
    ROHashStructure hs = getHashStructure( firstHash );
    if ( hs == null ) return null;    
    return hs.getObject( name.substring( firstSep+1 ) );
  }
  
  public String getString( String name )
  {
    return String.valueOf( getObject( name ) );
  }
  
  public String getString( String name, String defaultValue )
  {
    String value = getString( name );
    return value == null ? defaultValue : value;
  }
  
  public URL getURL( String name )
  {
    return (URL) getObject( name );
    
  }
  
  public URL getURL( String name, URL defaultValue )
  {
    URL value = getURL( name );
    return value == null ? defaultValue : value;
  }
  
  public Set<String> keySet()
  {
    return Collections.unmodifiableSet( _data.keySet() );
  }
  
  public int size()
  {
    return _data.size();
  }
  
}
